<template>
  <div class="device-tree-box">
    <div class="qn-device-tree" v-loading="treeLoading">
      <div class="scroll-content" v-if="!treeLoading && deviceTree.length > 0">
        <el-tree
          ref="qnTree"
          class="tree-content"
          :props="props"
          :load="loadNode"
          node-key="id"
          :highlight-current="true"
          :data="deviceTree"
          empty-text="未查询到数据"
          @node-expand="handleExpand"
          @node-click="clickNode"
          @node-collapse="handleCollapse"
          :filter-node-method="filterNode"
          lazy
          :default-expanded-keys="current_node"
          :current-node-key="select_node"
        >
          <div slot-scope="{ node, data }">
            <!-- 直播视频 -->
            <span v-if="!model" class="custom-tree-node"
              :class="online_Status(data, node)? 'node-text':'device__disabled'"
              :title="online_Status(data, node)?'':'离线'" >
              <!-- 网关icon -->
              <i v-if="!node.data.deviceId" :class="data.isOnline==1||data.online==1?'iconfont icon-gateway':'iconfont icon-gateway iconColor'"></i>
              <template v-else>
                <!-- 设备icon "摄像头" -->
                <i :class="iconDevice(node.data.status, node.data.type)" class="iconfont icon-device"></i>
                <i v-if="node.checked" class="icon-video"></i>
              </template>
              <span>{{ node.label }}</span>
              <el-tooltip content="没有绑定存储模板!" placement="top">
                <div v-if="node.data.deviceId && node.data.recordTemplateId==null" class="point-red"></div>
              </el-tooltip>

            </span>
            <!-- 历史回放视频 -->
            <span v-if="model" class="custom-tree-node node-text" >
              <i v-if="!node.data.deviceId" class="iconfont icon-gateway"></i>
              <template v-else>
                <i :class="iconDevice(node.data.status, node.data.type)" class="iconfont icon-device"></i>
                <i v-if="node.checked" class="icon-video"></i>
              </template>
              <span>{{ node.label }}</span>
              <el-tooltip content="没有绑定存储模板!" placement="top">
                <div v-if="node.data.deviceId && node.data.recordTemplateId==null" class="point-red"></div>
              </el-tooltip>
            </span>
          </div>
        </el-tree>
      </div>
      <Empty v-if="!treeLoading && deviceTree.length === 0" />
    </div>
  </div>
</template>

<script>
import Empty from "@/components/Empty/index.vue";
// import {
//   getDeviceTree,
//   getDeviceState,
//   getDeviceTreeNew,
//   getDeviceResList,
// } from "@/api/home.js";
import "jquery.nicescroll";

export default {
  components: { Empty },
  props: {
    grid_len: {   // 宫格数量, 可播放视频数量的上限
      type: [String, Number],
      default: 1,
    },
    model: {   // 0直播视频,  1历史视频
      type: [String, Number],
      default: 0,
    },
    grid_select: {   // 当前被选择中的 宫格位置序号
      type: [String, Number],
      default: -1,
    }
  },
  data() {
    return {
      point_red: false,   // 是否绑定了 存储模板
      deviceTree: [],   // 存: 所有节点的数据
      deviceTree2: [],   // 存: 城市节点的数据
      // grid_select: -1, // 被选中的 宫格位置

      checkedNodes: new Array(1), // 选中的node集合
      //change_icon: false,   // 页面切换当前icon 是否显示
      replaceNum: 0, // 替换的视频 宫格位置号
      current_node: [],   // 当前展开的节点
      select_node: '',   // 当前选中的节点


      filterText: "",
      treeLoading: true,   // 播放树的 数据是否正在加载中
      treeScroll: null,
      // time: "", // 定时器
      // gatewayState: "",
      // deviceState: "",
      // channelState: "",
      // dataListNew: [],
      // total: 0,
      // pageNo: 1,
      // pageSize: 15,
      // meauIndex: 0,
      props: {
        label: (data, node) => {
          if (node.level === 1) {
            // 第一层lable为name字段
            return data.name;
          } else if (node.level === 2 || node.level === 3) {
            // 第二三层lable为name字段
            return data.name;
          }
        },
        isLeaf: (data, node) => {
          if (node.level === 3) {
            // 第三层没有子节点
            return true;
          }
        },
      },

      gatewayId: "",   // 城市Id (网关ID)
      gatewayIndex: '',   // 城市编号 (网关编号)

      // currLevel: "",   // 当前被选中的 节点级别
      // currSignal: '',   // level==1, 存放当前被选中节点的 基础信息
      // currChannel: '',   // level==2, 存放当前节点的 数据信息

    };
  },
  computed: {
    iconDevice() {   // 摄像头icon
      return (status, type) => {
        let result = "icon-device" + type;
        if (!status) {
          result += " icon-device__disabled";
        }
        return result;
      };
    },
    // isLable解决设备在线的问题
    online_Status() {
      return (data, node) => {
        if(data.isLabel == 1) {
          return true
        }
        else {
          if((data.isOnline==1||data.online==1) || (node.parent.data.type==2  && node.parent.data.isOnline == 1)) return true
          else return false
        }
      }

    }

  },
  mounted() {
    this.getTreeDataNew();   // 页面挂载完毕, 发网络请求 获取设备列表
    this.current_node = this.$store.getters.current_node
    if(this.current_node.length == 3) {
      this.select_node = this.current_node[2]
      let data_keys = Object.keys(this.$store.getters.save_data)
      if(data_keys.length > 0 && this.model==1) {
        this.clickNode(this.$store.getters.save_data.data, this.$store.getters.save_data, 'change')
      }
    }
  },
  beforeDestroy() {
    if (this.treeScroll) {
      this.treeScroll.resize();
    }
    // if (!this.model) window.clearInterval(this.time);
  },
  watch: {
    grid_len(newVal, oldVal) {   // 监听宫格数量的变化 1, 4, 9, 12, 16, 24
      let remindval = newVal < oldVal ? newVal : oldVal; // 所要保留视频数量的上限
      let resultArr = [];
      if (this.grid_select !== -1) {   // 当前有被选中的宫格
        resultArr.push( this.checkedNodes[this.grid_select] )
        remindval = remindval - 1;
      }

      if(newVal > oldVal){   // 如果宫格数变大
        for (let i = 0; i < oldVal; i++) {
          if ( this.checkedNodes[i] && this.checkedNodes[i].checked && i !== this.grid_select) {
            resultArr.push(this.checkedNodes[i])
          }
        }
      }
      else {   // 宫格数变小
        let count = 0
        for (let i = 0; i < oldVal; i++) {
          if( this.checkedNodes[i] && this.checkedNodes[i].checked && i != this.grid_select && count < remindval) {
            resultArr.push(this.checkedNodes[i])
            count++
          }
          else if( this.checkedNodes[i] && this.checkedNodes[i].checked && i !== this.grid_select) {
            this.checkedNodes[i].checked = false;   // 关闭其余视频??? ###
          }
        }
      }

      this.checkedNodes = new Array(newVal)   // 根据宫格数, 更改数组长度

      this.replaceNum = 0;
      this.grid_select = -1;

      for (let i = 0; i < resultArr.length; i++) {
        // this.checkedNodes[i] = resultArr[i];
        this.$set(this.checkedNodes, i, resultArr[i])

        if (resultArr[i]) {
          this.$emit("node-click", resultArr[i].data, resultArr[i].checked, i, this.gatewayIndex);   // 打开视频 ??? ###
        }
        // else {
        //   this.$emit('node-click', null, false, i)
        // }
      }
    },
  },


  methods: {
    // 当被展开的时候, 触发的函数========================================================
    handleExpand(data, node, self) {
      this.handleChangeScroll();
    },
    // 当被折叠起来的时候, 触发的函数
    handleCollapse(data, node, self) {
      this.handleChangeScroll();
    },
    // 展开,折叠交替变化触发
    handleChangeScroll() {
      const _this = this;
      // element collapse-transtion动画完成后再更新滚动条
      setTimeout(() => {
        if (_this.treeScroll) {
          _this.treeScroll.resize();
        }
      }, 200);
    },
    // 网络请求: 分页获取设备列表========================================================
    getTreeDataNew() {
      getDeviceTreeNew({})
        .then((res) => {
          if (res.data.code === 0) {
            this.treeLoading = false;
            this.deviceTree = res.data.data;
            // 分页
          } else {
            this.treeLoading = false;
            this.deviceTree = [];
          }
        })
        .catch((err) => {
          this.treeLoading = false;
          this.deviceTree = [];
          this.$message.error(err.message);
        });
    },
    // 加载数据的钩子，当且仅当 lazy == true 时生效===================================================
    loadNode(node, resolve) {
      if (node.level === 0) {   // level == 0 所有数据,整个树
        return resolve(this.deviceTree);
      }
      else if (node.level === 1) { // level == 1 某个城市所有分院
        this.gatewayId = node.data.id;   // 城市id
        this.gatewayIndex = node.data.gatewayIndex;   // 城市编号
        // 动态请求该城市所有数据
        getDeviceResList({ gatewayId: this.gatewayId })
          .then((res) => {
            if (res.data.code === 0) {
              this.deviceTree2 = res.data.data;
              return resolve(this.deviceTree2);
            }
          })
          .catch((err) => {
            this.$message.error(err.message);
          });
      }
      else if (node.level === 2) {   // 具体某个分院
        return resolve(node.data.channelList);   // channelList 摄像设备列表
      }
      else if (node.level > 2) {
        return resolve([]);
      }
    },
    // 点击节点触发该函数, (不同level 有不同的响应)
    clickNode(data, node, page, self) {
      // console.log(node)
      let select_arr = []
      function addParent(node) {   // 获取当前节点的父节点(解决不同页面切换时, 聚焦当前节点的问题)
        if(node && node.parent && typeof(node.parent.key)!= 'undefined' && node.parent.key != null) {
          select_arr.push(node.parent.key)
          addParent(node.parent)
        }
      }
      addParent(node)
      if(node.expand) {select_arr.push(node.key)}   // 根据展开与否

      if(node.level == 3) {   // 点击的是设备, 存上当前节点
        this.$store.commit("SAVE_DATA", node)
      }
      this.$store.commit("SET_NODE", select_arr)

      // 如下三个变量,页面 暂时未用到
      // this.currLevel = node.level
      // if (node.level === 1) this.currSignal = node.data;   // level == 1
      // if (node.level === 2) this.currChannel = node.data;   // level == 2

      // isOnline分院是否在线, online摄像头设备是否在线

      // model==1历史模式----------------------------------------
      if(this.model==1) {
        if (data && data.deviceId && data.status !== 0) {   // 有设备id 并且状态值不为 0   (可以将data.deviceId 换成 node.level)
          if(node.checked && page != 'change') {   // 被点击的摄像头 正在播放,  则去关闭视频
            this.toggleVideo(0, node, data, false, this.gatewayIndex)   // 关闭当前视频
          }
          else{
            if(this.checkedNodes[0] && page != 'change') {
              this.toggleVideo(0, this.checkedNodes[0], this.checkedNodes[0].data, false, this.gatewayIndex)   // 关闭原来视频
            }
            this.toggleVideo(0, node, data, true, this.gatewayIndex)   // 打开当前视频
          }
        }
        return
      }
      // model==0 直播-----------------------------------------------------
      else if(this.model==0) {
        if(node.level == 1 || node.level == 2) {   // 直播模式: 不在线
          return
        }
        else if( node.level == 3 && data.status !== 0 && (data.online==1 || (node.parent.data.type==2  && node.parent.data.isOnline == 1)) ) {   // 以下是在线视频, 直播状态被点击
          if(node.checked) {   // 被点击的摄像头 正在播放,  则去关闭视频
            console.log('被点击的摄像头, 正在播放');
            const position = this.getNodePositionByKey(data.id);   // 通过摄像头id 获取到播放该视频的 宫格位置号
            this.toggleVideo(position, node, data, false, this.gatewayIndex)   // 关闭当前视频
            // this.toggleVideo(position, undefined, this.checkedNodes[position].data, false, this.gatewayIndex)
          }
          else if (this.grid_select === -1) {   // 未处于播放状态,并且无活跃宫格, 找一个位置去播放视频
            console.log('被点击的摄像头, 未处于播放状态, 无活跃宫格');
            const position = this.getInsertPosition(node);

            this.toggleVideo(position, node, data, true, this.gatewayIndex)   // 打开当前视频
          }
          else {   // 未处于播放状态, 在活跃的宫格中 打开视频
            console.log('被点击的摄像头, 未处于播放播放, 有活跃宫格');
            if(this.checkedNodes[this.grid_select] != undefined) {   // 活跃的宫格里边有视频, 先关闭原来的
              this.toggleVideo(this.grid_select, this.checkedNodes[this.grid_select], this.checkedNodes[this.grid_select].data, false, this.gatewayIndex)   // 关闭原来视频
            }
            this.toggleVideo(this.grid_select, node, data, true, this.gatewayIndex)   // 打开视频
          }
          return
        }
      }
    },
    // 获得一个宫格位置, 用来播放摄像头
    getInsertPosition(node) {
      let position = -1;
      for (let i = 0; i < this.grid_len; i++) {
        // 如果有空位置，返回第一个空位置作为插入点
        if (position === -1 && this.checkedNodes[i] == undefined) {
          position = i;
          break;
        }
      }
      if (position === -1) {   // 没有空位置了，按照replaceNum替换视频
        position = this.replaceNum % this.grid_len;
        this.replaceNum++;
        // 需要将替换  让原来的视频取消播放
        this.toggleVideo(position, this.checkedNodes[position], this.checkedNodes[position].data, false, this.gatewayIndex)   // 关闭原来视频
      }
      return position;
    },
    // 通过摄像头id 获到播放该视频的宫格位置号
    getNodePositionByKey(key) {
      let position = -1;
      for (let i = 0; i < this.grid_len; i++) {
        if (this.checkedNodes[i] && this.checkedNodes[i].data.id === key) {
          position = i;
          break;
        }
      }
      return position;
    },
    // 父组件通过ref 调用该函数 关闭视频
    closeVideo(position) {
      this.toggleVideo(position, this.checkedNodes[position], this.checkedNodes[position].data, false, this.gatewayIndex)
    },
    // 关闭\打开 视频
    toggleVideo(position, node, data, toggle, gatewayIndex) {
      this.$emit("node-click", data, toggle, position, gatewayIndex, node);
      node.checked = toggle
      // this.change_icon = toggle
      if(toggle) this.$set(this.checkedNodes, position, node)
      else { this.$set(this.checkedNodes, position, undefined) }   // ### 关闭视频
    },

    // 过滤: 当前的节点是否显示出来
    filterNode(value, data) {
      if (!value) return true;   // 没有索引关键字, 则所有节点都显示
      return data.name.indexOf(value) !== -1;   // 有索引关键字,则带关键字的才显示
    },
    // 父组件点击搜索, 会通过ref调用这个函数
    searchTree(val) {   // backview.vue文件  通过ref调用了这个函数
      this.$refs.qnTree.filter(val);   //filter是el-tree自带的方法 接收一个任意类型的参数，该参数会在 filter-node-method 中作为第一个参数
    },
  },

};
</script>

<style lang="scss">
// 基础颜色
$color-primary: #2E89FF; // 系统主色
$color-success: #0EC00F; // 成功
$color-warning: #FF941D; // 警告
$color-danger: #FF6565;  // 错误
$color-info: #BBBBBB;    // 信息
// 背景颜色
$header-background: #2E89FF; // 头部背景色
$app-background: #E9E9F0; // 全局背景色
$page-background: #E9E9F0; // 页面背景色
$page-background-light: #F7F7F9; // 布局背景色
// 字体颜色
$font-primary: #333;    // 字体正文颜色(黑色)
$font-result: #666;     // 字体提示颜色(灰色)
$font-info: #999;       // 字体提示颜色(灰色)
$font-pop: #646464;     // pop弹框字体颜色

$hover-backgoround: #DEE7F9; // 列表hover背景颜色
$border-color: #E1E1E1; // 线的颜色
$border-color-search: #BBBBBB; // 搜索框border颜色
$tr-light-background: #E7EDF8;
$tr-background: #F7F7F9;
$th-background: #DEE7F9;


// scrollbar
$scrollbar-width:           6px;
$scrollbar-height:          6px;
$scrollbar-track-color:     transparent;
$scrollbar-thumb-color:     #bbb;
//===========================================

.device-tree-box {
  height: 100%;
}
// .device-tree-title {
//   font-family:Microsoft YaHei;
//   font-weight:400;
//   width: 100%;
//   height: 60px;
//   display: flex;
//   justify-content: space-between;
//   align-items: center;
//   background: #F8F8F8;
//   padding: 0 10px;
//   .title {
//     font-size:18px;
//     color: #333;
//   }
//   .tree-search {
//     /*margin-bottom: 10px;*/
//     // flex: 0 0 40px;
//     // margin-left: 15px;
//     // width: calc(100% - 30px);
//     width: 60%;
//     .el-input__suffix {
//       width: 32px;
//       height: 32px;
//       background:#fff;
//       border-radius:0px 4px 4px 0px;
//       border: 1px solid #DCDFE6;
//       top: 0px;
//       right: 0px;
//       box-sizing: border-box;
//     }
//     .search-icon {
//       color: #aaa;
//       cursor: pointer;
//       font-size: 16px;
//       // font-weight: bold;
//       height: 32px;
//     }
//   }
// }
.qn-device-tree {
  height: 100%;
  // height: calc(100% - 60px);
  display: flex;
  flex-direction: column;
  padding-left: 30px;

  .scroll-content {
    height: 100%;
    // position: relative;
    overflow-y: scroll !important;
  }
  .tree-content {
    width: 100%;
  }
  .el-tree-node {
    width: 100% !important;
    &.is-expanded {
      .el-tree-node__expand-icon {
        color: $color-primary;
      }
      .custom-tree-node {
        .icon-gateway {
          color: $color-primary;
        }
        .iconColor {
          color: #bbbbbb;
          cursor: default;
        }
        .pNode {
          color: $color-primary;
        }
      }
    }
  }
  .el-tree-node__content {
    width: 100%;
    padding-right: 10px;
  }
  .el-tree-node__expand-icon {
    font-family: "iconfont" !important;
    font-size: 12px;
    font-style: normal;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    &.el-icon-caret-right:before {
      content: "\e663";
    }
    &.is-leaf {
      color: transparent !important;
    }
  }
  .el-icon-caret-right {
    color: $font-result;
    padding-left: 0;
  }
  .custom-tree-node {
    // background-color: aqua;
    .point-red {
      margin-left: 5px;
      width: 6px;
      height: 6px;
      cursor: pointer;
      display: inline-block;
      background-color: #f33;
      border-radius: 50%;
      transform: translateY(-3px);
    }
    position: relative;
    display: inline-block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    word-break: break-all;
    .icon-gateway {
      color: $font-result;
      margin-right: 3px;
    }
    .icon-device {
      color: $font-result;
      margin-right: 2px;
    }
    .icon-video {
      position: absolute;
      left: 8px;
      top: 5px;
      width: 14px;
      height: 14px;
      display: inline-block;
      background-image: url("img/video.png");
      background-size: cover;
    }
    .node-text {
      color: $font-result;
    }
    &.device__disabled {
      cursor: default;
      color: #bbbbbb !important;
      // cursor: not-allowed;
      .icon-device__disabled {
        color: rgb(134, 134, 134);
      }
    }
  }
  .notOnline {
    color: gold;
  }
}
.nicescroll-cursors {
  position: static !important;
  top: 0px !important;
  height: 0px !important;
  background: #fff !important;
  width: 0px !important;
}
</style>

